package cn.yangliu.nacos.oauth2.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;

/**
 * The interface Resource server config.
 *
 * @author 问道于盲
 * @date 2019 -03-27
 */
@Configuration
@EnableResourceServer
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    /**
     * current class instance's member.
     * The Token store.
     */
    @Autowired
    private TokenStore tokenStore;

    /**
     * current class instance's member.
     * The Translator.
     */
    @Autowired
    private Oauth2WebResponseExceptionTranslator translator;

    /**
     * Configure.
     *
     * @param resources the resources
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) {
        resources
                .tokenStore(tokenStore)
                .resourceId("resourceId").stateless(true);

        AccessDeniedHandler accessDeniedHandler = new OAuth2AccessDeniedHandler();
        ((OAuth2AccessDeniedHandler) accessDeniedHandler)
                .setExceptionTranslator(translator);
        resources.accessDeniedHandler(accessDeniedHandler);


        AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
        ((OAuth2AuthenticationEntryPoint) authenticationEntryPoint)
                .setExceptionTranslator(translator);
        resources.authenticationEntryPoint(authenticationEntryPoint);
    }

    /**
     * Configure.
     *
     * @param http the http
     * @throws Exception the exception
     */
    @Override
    public void configure(HttpSecurity http) throws Exception {
    	/*
    	 注意：
    	 1、必须先加上： .requestMatchers().antMatchers(...)，表示对资源进行保护，也就是说，在访问前要进行OAuth认证。
    	 2、接着：访问受保护的资源时，要具有哪里权限。
    	 ------------------------------------
    	 否则，请求只是被Security的拦截器拦截，请求根本到不了OAuth2的拦截器。
    	 同时，还要注意先配置：security.oauth2.resource.filter-order=3，否则通过access_token取不到用户信息。
    	 ------------------------------------
    	 requestMatchers()部分说明：
    	 Invoking requestMatchers() will not override previous invocations of ::
    	 mvcMatcher(String)}, requestMatchers(), antMatcher(String), regexMatcher(String), and requestMatcher(RequestMatcher).
    	 */
        http.authorizeRequests()
                .antMatchers("/doc.html","/webjars/**","/swagger-resources/**","/v2/**")
                .permitAll()
                .and()
                .antMatcher("/user/**").authorizeRequests()
                .anyRequest()
                .authenticated()
                .and()
                .formLogin()
                .permitAll()
                .and()
                .csrf().disable();
    }

}
